#! /usr/bin/perl

use FindBin qw($Bin);
use lib "$Bin/../lib";  

###################################################################
# CONFIGURATION
# the path to your maude v1.05 binary
$maude = "maude.linux";
###################################################################

$ptltl = "$Bin/ptltl.maude";

# main begins
$fn = "ptltltmp";
# try to get access for all needed files
if (!open(ptltlmaude, $ptltl)){
    print "Couldn't access file $ptltl.\n" .
	"Please edit the file bc-run and configure it as indicated.\n";
    exit;
}
close ptltlmaude;
if (!open(maudefile, ">$fn.maude")){
    print "Couldn't open the file $fn.maude for writing.\n" ;
    exit;
}
if (!open(tmpfile, ">$fn.mout")){
    print "Couldn't open the file $fn.out for writing.\n";
    exit;
}
close tmpfile;

@predicates =();
@predicate2expr = ();
@program=();
@fncts = ();
@events = ();
$formula="";
$flag = 0;
while (<>){
    s/\/\/.*//;
    if ($flag == 0) {
	if (/Predicate\s+(\S+)\s*\:(.*)\;/) {
	    $predicates[$#predicates+1] = $1 ;
	    $predicate2expr{$1} = "($2)";	
	} else {
	    if (/Event\s+(\S+)\s*\:(.*)\;/) {
		$fncts[$#fncts+1] = $1 ;
	    } else{
		if (/Formula\s*\:/) {
		    s/;//g;
		    s/Formula\s*\://;
		    s/\(\*\)/{*}/g;
		    s/\)s/}s/g;
                    s/\)w/}w/g;
	            s/\!|\/\\|\\\/|\-\>|\<\-\>|\+\+|\{\*\}|\[\*\]|\<\*\>|\[|\}s|\}w/ $& /g;
	            s/\s+/ /g;
	            for ($i = 0; $i <= $#fncts; $i ++){
			if (/start\($fncts[$i]\)/){
			    $events[$#events+1] = "\$start-$fncts[$i]";
			    s/start\($fncts[$i]\)/\$start\-$fncts[$i]/g;
			}
			if (/end\($fncts[$i]\)/){
			    $events[$#events+1] = "\$end-$fncts[$i]";
			    s/end\($fncts[$i]\)/\$end\-$fncts[$i]/g;
			}
			if (/(.)$fncts[$i]/){
			    $tmp = $1;
			    if (! ($tmp =~ /\-/)){
				$events[$#events+1] = "\$end-$fncts[$i]";
				s/$tmp$fncts[$i]/$tmp\$end\-$fncts[$i]/g;
			    }
			}
	            }
	            $formula=$_;
	            $flag = 1;
                 }
            }
	}
     } else {
        if ((/Violation\sHandler/) || (/Validation\sHandler/)){
	    $flag = 0;
        } else { 
	    s/;//g;
	    s/\(\*\)/{*}/g;
	    s/\)s/}s/g;
            s/\)w/}w/g;
            s/\!|\/\\|\\\/|\-\>|\<\-\>|\+\+|\{\*\}|\[\*\]|\<\*\>|\[|\}s|\}w/ $& /g;
            s/\s+/ /g;
            for ($i = 0; $i <= $#fncts; $i ++){
		if (/start\($fncts[$i]\)/){
		    $events[$#events+1] = "\$start-$fncts[$i]";
		    s/start\($fncts[$i]\)/\$start\-$fncts[$i]/g;
		}
		if (/end\($fncts[$i]\)/){
		    $events[$#events+1] = "\$end-$fncts[$i]";
		    s/end\($fncts[$i]\)/\$end\-$fncts[$i]/g;
		}
		if (/(.)$fncts[$i]/){
		    $tmp = $1;
		    if (! ($tmp =~ /\-/)){
			$events[$#events+1] = "\$end-$fncts[$i]";
			s/$tmp$fncts[$i]/\$end\-$fncts[$i]/g;
		    }
		}
            }
	    $formula = $formula.$_; 
	}
     }
}

print maudefile "in $ptltl \n\n" ;
print maudefile "fmod TEST is\n
  pr PTLTL-TRANS .\n
  ops " ;
for ( $i = 0 ; $i <= $#predicates ; $i ++) {
    print maudefile "$predicates[$i] ";
}
for ( $i = 0 ; $i <= $#events ; $i ++) {
    print maudefile "$events[$i] ";
}

print maudefile " : -> Atom .\n" ;
print maudefile "  op formula : -> ptLTLExpr .\n" ;
print maudefile "  eq formula = ( $formula ) .\n" ;
print maudefile "endfm \n" ;
print maudefile "red trans(! formula) .\nquit \n";

close maudefile;
# end writing maude file

system("$maude $fn.maude > $fn.mout");

open (tmpfile, "$fn.mout");     

while (<tmpfile>){
    if (/^result\s+Output:\s*\[(.+)/){
        $output = $1 ;
        $mark = 1 ;
    } else{
        if (/Bye./) {
	    last ;
        } else{
	    if ($mark==1){
		s/\n//;
		$output = "$output$_";	    
	    }
	}
    }
}
close tmpfile;

if (!(defined($output))){
    print "Past Time LTL: Cannot deal with the logic input.\n";
#    unlink "$fn.maude";
#    unlink "$fn.mout";
    exit 1;
}

$output=~ s/\]\s*\n//;
$output=~ s/\s+/ /g;
$output= " $output";
for ( $i = 0 ; $i <= $#predicates ; $i ++) {
    $output =~ s/(\W)$predicates[$i]/$1$predicate2expr{$predicates[$i]}/g;
}
@outputs = split(/,/ , $output) ;
@statements = split(/;/ , $outputs[1]);
@initStatements = split(/;/ , $outputs[3]);


print "//Declaration\n";
$ln = $#statements + 1;
print "boolean[] \$pre = new boolean[$ln];\n";
print "boolean[] \$now = new boolean[$ln];\n";

for ($i = 0; $i <= $#events; $i ++){
    $item = $events[$i];
    $item =~ s/\$(.+)\-(.+)/$1($2)/g;
    print "fnct $events[$i] = $item;\n";
}

#print "//Predicates\n";
#print @program ;

print "//Initialization\n";
foreach $item (@initStatements) {
    $item =~s/^\s*\((.*)\)\s*$/$1/g;
    $item =~s/^\s+//g;
    print "$item;\n";
}

print "//Monitoring body\n";
for ($i = 0;$i < $ln ; $i ++){
    print "\$pre[$i] = \$now[$i] ;\n";
}
foreach $item (@statements) {
    $item =~s/^\s*\((.*)\)\s*$/$1/g;
    $item =~s/^\s+//g;
    print "$item;\n";
}

print "//Failure condition\n";
print "$outputs[0]\n";

unlink "$fn.maude";
unlink "$fn.mout";

